from farstyle.models import CSS, JS
from farstyle.views import css, js
from farstyle.utils import combine_js, combine_css
from farstyle import settings

from django.template import Library, Node
from django.template import TemplateSyntaxError
from django.template import resolve_variable
from django.core.cache import cache
from django.utils.safestring import SafeUnicode

import md5
import os
from cStringIO import StringIO

register = Library()

CSS_TAG = u'<link rel="stylesheet" type="text/css" href="%(url)s" media="%(media)s" />'
JS_TAG  = u'<script type="text/javascript" src="%(url)s"></script>'

def strip_quotes(s):
    if s[0] == s[-1] and s[0] in ('"', "'"):
        return s[1:-1]
    return s

class JavaScriptNode(Node):
    def __init__(self, params):
        self.params = params

    def render(self, context):
        groups = JS.objects.grouped(context, self.params)
        if settings.DEBUG:
            tags = self.individual_tags(groups, context)
        else:
            tags = self.grouped_tags(groups, context)
        return SafeUnicode('\n'.join(tags))

    def grouped_tags(self, groups, context):
        tags = []
        for group in groups:
            path = combine_js(group, context)
            tags.append(JS_TAG % {
                'url': settings.MEDIA_URL + path,
            })
        return tags        

    def individual_tags(self, groups, context):
        newlist = []
        for group in groups: newlist += group['assets']
        return [JS_TAG % {
            'url': '%s?%s' % (js.get_absolute_url(), js.hash(context)),
        } for js in newlist]

@register.tag
def js_assets(parser, token):
    """
    Render a set of <script> tags linking to javascript assets
    
    Parameters:
        params - optional text passed to asset condition code

    Example usage:
    
        {% js_assets %}
    """
    bits = token.split_contents()
    params = [ strip_quotes(a) for a in bits[1:] ]
    return JavaScriptNode(params)

class CSSNode(Node):
    def __init__(self, params):
        self.params = params

    def render(self, context):
        groups = CSS.objects.grouped(context, self.params)
        if settings.DEBUG:
            tags = self.individual_tags(groups, context)
        else:
            tags = self.grouped_tags(groups, context)
        return SafeUnicode('\n'.join(tags))

    def grouped_tags(self, groups, context):
        tags = []
        for group in groups:
            path = combine_css(group, context)
            tags.append(CSS_TAG % {
                'url': settings.MEDIA_URL + path,
                'media': group['assets'][0].media,
            })
        return tags        

    def individual_tags(self, groups, context):
        newlist = []
        for group in groups: newlist += group['assets']
        return [CSS_TAG % {
            'url': '%s?%s' % (css.get_absolute_url(), css.hash(context)),
            'media': css.media,
        } for css in newlist]

@register.tag
def css_assets(parser, token):
    """
    Render <link> tags linking to css assets
    
    Parameters:
        params - optional text passed to asset condition code

    Example usage:
    
        {% css_assets %}
        <!--[if lt IE 8]>
        {% css_assets "ie7" %}
        <![endif]-->
    """
    bits = token.split_contents()
    params = [ strip_quotes(a) for a in bits[1:] ]
    return CSSNode(params)

class FarFutureNode(Node):
    def __init__(self, path):
        self.path = path

    def render(self, context):
        mtime = os.path.getmtime(os.path.join(settings.MEDIA_ROOT, self.path))
        path, name = os.path.split(self.path)
        name, ext = name.rsplit('.', 1)
        new_path = settings.FAR_FUTURE_PATH % {
            'path': path,
            'name': name,
            'unique': str(mtime),
            'ext': ext,
        }
        return new_path

@register.tag
def far_future(parser, token):
    """
    Render a far future caching-friendly URL to a media file.

    Parameters:
        path - media file path (relative to MEDIA_ROOT)

    Example usage:
    
        {% far_future "images/never_changing_photo.jpg" %}
    """
    try:
        tag_name, path = token.split_contents()
    except ValueError:
        raise template.TemplateSyntaxError, '%r requires a single argument: path to a media file.' % tag_name

    return FarFutureNode(strip_quotes(path))
